import logging
import re

import requests

logger = logging.getLogger(__name__)

class TransitRouteService:
    def __init__(self, api_key):
        self.base_url = "https://api.map.baidu.com/directionlite/v1/transit"
        self.api_key = api_key
        self.city_cache = set()

    def validate_coordinate(self, coord):
        try:
            lat_str, lng_str = coord.split(',')
            if len(lat_str.split('.')[1]) > 6 or len(lng_str.split('.')[1]) > 6:
                raise ValueError("小数点精度超过6位")
            return True
        except (ValueError, IndexError, AttributeError) as e:
            logger.error(f"坐标验证失败: {coord} | 错误: {str(e)}")
            return False

    def get_transit_route(self, origin, destination, city_code=None, tactics=13, origin_uid=None, destination_uid=None, coord_type='bd09ll', ret_coordtype='bd09ll', steps_info=0, sn=None, timestamp=None):
        # 增强参数校验
        if not all(self.validate_coordinate(c) for c in [origin, destination]):
            raise ValueError("坐标格式应为'纬度,经度'且小数精度不超过6位")
        
        # UID格式校验（示例：B488A10ACD）
        if origin_uid and not re.match(r'^B[A-Z0-9]{9}$', origin_uid):
            raise ValueError("origin_uid格式不合法")
        if destination_uid and not re.match(r'^B[A-Z0-9]{9}$', destination_uid):
            raise ValueError("destination_uid格式不合法")
        
        # 坐标类型校验
        if coord_type not in ['bd09ll', 'bd09mc', 'gcj02', 'wgs84']:
            raise ValueError("无效的输入坐标类型，可选值：bd09ll/bd09mc/gcj02/wgs84")
        if ret_coordtype not in ['bd09ll', 'gcj02']:
            raise ValueError("无效的输出坐标类型，可选值：bd09ll/gcj02")
        
        # SN校验规则
        if sn and not timestamp:
            raise ValueError("SN参数需要配合timestamp使用")

        params = {
            'origin': f'{origin.split(",")[1]},{origin.split(",")[0]}',
            'destination': f'{destination.split(",")[1]},{destination.split(",")[0]}',
            'ak': self.api_key,
            'tactics': tactics,
            'city': city_code or '',
            'origin_uid': origin_uid or '',
            'destination_uid': destination_uid or '',
            'coord_type': coord_type,
            'ret_coordtype': ret_coordtype,
            'steps_info': steps_info,
            'sn': sn or '',
            'timestamp': timestamp or ''
        }

        try:
            response = requests.get(self.base_url, params=params, timeout=10)
            response.raise_for_status()
            data = response.json()

            if data.get('status') != 0:
                logger.error(f"API错误: {data.get('message')}")
                return None

            return self._parse_response(data)
        except requests.exceptions.RequestException as e:
            logger.error(f"请求异常: {str(e)}")
            return None

    def _format_transfer_instruction(self, step):
        base = step.get('instruction','')
        transfers = [s['name'] for s in step.get('stations',[]) if s.get('is_transfer')]
        if transfers:
            return f"{base}（换乘站：{'→'.join(transfers)}）"
        return base

    def _parse_response(self, data):
        # 状态码处理
        status_map = {
            1001: '没有公交方案',
            1002: '不支持跨域出行',
            1003: '起终点附近没有车站'
        }
        if data.get('status') in status_map:
            return {'error': status_map[data['status']], 'code': data['status']}

        # 公交类型映射
        VEHICLE_TYPES = {
            0: '日间公交',1: '地铁',2: '机场巴士(去)',3: '有轨电车',4: '机场巴士(返)',
            5: '旅游专线',6: '夜班车',7: '机场巴士',8: '轮渡',9: '其他',
            10: '快车',11: '慢车',12: '机场快轨(去)',13: '机场快轨(返)',14: '机场环线'
        }

        routes = []
        for route in data.get('result', {}).get('routes', []):
            # 出租车费用解析
            taxi_detail = route.get('taxi', {}).get('detail', {})
            taxi_info = {
                'day_type': taxi_detail.get('desc', '白天'),
                'start_price': taxi_detail.get('start_price', 0),
                'km_price': taxi_detail.get('km_price', 0),
                'total': taxi_detail.get('total_price', 0),
                'distance': taxi_detail.get('distance', 0),
                'duration': taxi_detail.get('duration', 0),
                'remark': taxi_detail.get('remark', '')
            } if route.get('taxi') else None

            # 线路价格计算
            # 增强票价计算逻辑（分时段计算）
            line_prices = {
                'day': sum(t['line_price'] for t in route.get('line_price', []) if t.get('time_interval') == 'day'),
                'night': sum(t['line_price'] for t in route.get('line_price', []) if t.get('time_interval') == 'night'),
                'details': [
                    {
                        'type': VEHICLE_TYPES.get(t['line_type'], '其他'),
                        'price': t['line_price'],
                        'time_interval': t.get('time_interval', '全天')
                    } for t in route.get('line_price', [])
                ]
            }
            route_info = {
                'distance': route['distance'],
                'duration': route['duration'],
                'traffic': ['无', '畅通', '缓行', '拥堵'][route.get('traffic_condition', 0)],
                'price': sum(step.get('price', 0) for step in route.get('steps', [])),
                'transit_count': len([s for s in route.get('steps', []) if s.get('vehicle_type') != 'WALK']),
                'night_line': any(t.get('line_type') == 6 for t in route.get('line_price', [])),
                'line_prices': line_prices,
                'zone_price': route.get('zone_price', {'day': 0, 'night': 0}),
                'taxi_info': taxi_info,
                'steps': []
            }
            for step in route.get('steps', []):
                step_info = {
                    'instruction': self._format_transfer_instruction(step),
                    'vehicle': step.get('vehicle', {}).get('name', '步行'),
                    'vehicle_type': step.get('vehicle', {}).get('type', 'WALK'),
                    'stations': [{
                        'name': s['name'],
                        'uid': s.get('uid', ''),
                        'is_transfer': s.get('is_transfer', False),
                        'transfer_lines': s.get('lines', [])
                    } for s in step.get('stations', [])],
                    'exit': step.get('exit', {}).get('name', ''),
                    'duration': step.get('duration', 0),
                    'distance': step.get('distance', 0)
                }
                route_info['steps'].append(step_info)
            route_info['traffic'] = {
                'condition': route.get('traffic_condition', 0),
                'description': ['无', '畅通', '缓行', '拥堵'][route.get('traffic_condition', 0)]
            }
            
            # 统一数据结构
            route_info['origin'] = {
                'lng': data['result']['origin']['lng'],
                'lat': data['result']['origin']['lat']
            }
            route_info['destination'] = {
                'lng': data['result']['destination']['lng'],
                'lat': data['result']['destination']['lat']
            }
            for step in route.get('steps', []):
                step_info = {
                    'instruction': self._format_transfer_instruction(step),
                    'vehicle': step.get('vehicle', {}).get('name', '步行'),
                    'vehicle_type': step.get('vehicle', {}).get('type', 'WALK'),
                    'stations': [{
                        'name': s['name'],
                        'uid': s.get('uid', ''),
                        'is_transfer': s.get('is_transfer', False),
                        'transfer_lines': s.get('lines', [])
                    } for s in step.get('stations', [])],
                    'exit': step.get('exit', {}).get('name', ''),
                    'duration': step.get('duration', 0),
                    'distance': step.get('distance', 0)
                }
                route_info['steps'].append(step_info)
            routes.append(route_info)
        return routes

    def validate_city_code(self, code):
        if code in self.city_cache:
            return True
        
        # 通过百度API验证城市代码有效性
        url = f'https://api.map.baidu.com/place/v2/suggestion?query={code}&region=全国&output=json&ak={self.api_key}'
        try:
            response = requests.get(url, timeout=5)
            if response.json().get('status') == 0:
                for result in response.json().get('results', []):
                    if result.get('code') == code:
                        self.city_cache.add(code)
                        return True
            return False
        except Exception as e:
            logger.error(f'城市代码验证失败: {str(e)}')
            return False